package com.xbongbong.paas.service.dynamic.crm.strategy.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.service.dynamic.crm.strategy.AbstractDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.CommunicateDynamicStrategy;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicRefInfoDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.CommunicateBaseEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 *跟进
 *
 *@author weijianxun
 */
@Service("communicateDynamicStrategyImpl")
public class CommunicateDynamicStrategyImpl extends AbstractDynamicStrategy implements CommunicateDynamicStrategy {

    private final Logger LOG = LoggerFactory.getLogger(CommunicateDynamicStrategyImpl.class);

    private static final Map<String, Integer> refTextToLogTypeMap = new HashMap<>();

    static {
        refTextToLogTypeMap.put(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(), ProjectLogEnum.CUSTOMER_REF.getSubType());
        refTextToLogTypeMap.put(CustomerCommunicateEnum.CONTACT_ARRAY.getAttr(), ProjectLogEnum.CONTACT_REF.getSubType());
        // 合同和机会一样
        refTextToLogTypeMap.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr(), null);
    }

    @Resource
    private EsHelper esHelper;

    @Override
    public List<Integer> type() {
        return Arrays.asList(
                XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),
                XbbRefTypeEnum.CALL_CENTER.getCode()
        );
    }

    @Override
    @Async("dynamicThreadPool")
    public void save(DynamicSaveDTO dynamicSaveDTO) {
        try {
            customerCommunicateSaveUpRefDynamic(dynamicSaveDTO);
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.CommunicateDynamicStrategyImpl.save", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void batchDelete(DynamicDeleteDTO dynamicDeleteDTO) {
        try {
            FormDataDeleteBatchDTO formDataDeleteBatchDTO = dynamicDeleteDTO.getFormDataDeleteBatchDTO();
            List<Long> allowDeleteDataIds = dynamicDeleteDTO.getAllowDeleteDataIds();
            //查询编号
            BoolQueryBuilder builder = boolQuery();
            // 添加corpid,formId,del
            builder.filter(termQuery("corpid.keyword", formDataDeleteBatchDTO.getCorpid()));
            // builder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            builder.filter(termsQuery(StringConstant.DATA_ID, allowDeleteDataIds));
            List<PaasFormDataEntityExt> paasFormDataEntityExts = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, builder, PaasFormDataEntityExt.class, null);

            List<DynamicDTO> dynamicDTOS = new ArrayList<>(allowDeleteDataIds.size());
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                customerCommunicateBatchDeleteUpRefDynamic(paasFormDataEntityExt.getData(), formDataDeleteBatchDTO, dynamicDTOS);
            }
            insertDynamic(dynamicDTOS, formDataDeleteBatchDTO.getCorpid());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.CommunicateDynamicStrategyImpl.batchDelete", e);
        }
    }

    private void customerCommunicateSaveUpRefDynamic(DynamicSaveDTO dynamicSaveDTO) {
        SaasFormSaveDTO saasFormSaveDTO = dynamicSaveDTO.getSaasFormSaveDTO();

        PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        JSONObject data = paasFormDataEntity.getData();
        // 跟进信息
        String communicateInfo = data.getString(CommunicateBaseEnum.MEMO.getAttr());
        // 跟进时间
        // String communicateDateTime = DateTimeUtil.getStringEpochSecond(data.getLong(CommunicateBaseEnum.COMMUNICATE_TIME.getAttr()), DateTimeUtil.SDFYMDHM);
        UserEntity creator = dynamicSaveDTO.getCreator();
        List<DynamicDTO> dynamicDTOS = new ArrayList<>();

        List<String> memoHolder;

        DynamicRefInfoDTO dynamicRefInfoDTO = null;
        String memo;
        Integer businessType = saasFormSaveDTO.getBusinessType();
        if (Objects.equals(businessType, XbbRefTypeEnum.CALL_CENTER.getCode())) {
            memo = CrmLogMemoConstant.DYNAMIC_USER_COMMUNICATE_CALL_ADD;
            memoHolder = DynamicDTO.initMemoHolder(creator.getName());
            dynamicRefInfoDTO = DynamicRefInfoDTO.initDynamicRefInfoDTO(0L, businessType, communicateInfo);
        } else {
            if (Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                memo = CrmLogMemoConstant.DYNAMIC_USER_COMMUNICATE_IMPORT;
            } else {
                memo = CrmLogMemoConstant.DYNAMIC_USER_COMMUNICATE_ADD;
            }
            memoHolder = DynamicDTO.initMemoHolder(creator.getName());
            dynamicRefInfoDTO = DynamicRefInfoDTO.initDynamicRefInfoDTO(paasFormDataEntity.getId(), businessType, communicateInfo);
        }

        // 可以关联多联系人
        JSONArray contactIdArr = data.getJSONArray(CommunicateBaseEnum.CONTACT.getAttr());
        if (Objects.nonNull(contactIdArr) && !contactIdArr.isEmpty()) {
            List<Long> contactIds = contactIdArr.toJavaList(Long.class);
            for (int i = 0; i < contactIds.size(); i++) {
                DynamicDTO dynamicDTO = initDynamicDTO(creator.getUserId(), memo, null,
                        memoHolder, null, null, null);
                if (i == 0) {
                    fillRefInfoDynamicDTO(dynamicDTO, data);
                }
                dynamicDTO.setContactId(contactIds.get(i));
                // 区别于其他业务日志
                if (Objects.equals(businessType, XbbRefTypeEnum.CALL_CENTER.getCode())) {
                    dynamicDTO.setLogType(ProjectLogEnum.CALL_LOG.getSubType());
                } else {
                    // 客户旅程修复logType
                    // dynamicDTO.setLogType(BasicConstant.ZERO);
                    dynamicDTO.setLogType(ProjectLogEnum.CUSTOMER_COMMUNICATE_CREATE.getSubType());
                }
                if (Objects.nonNull(dynamicRefInfoDTO)) {
                    BeanUtil.copyProperties(dynamicRefInfoDTO, dynamicDTO, true);
                }
                dynamicDTOS.add(dynamicDTO);
            }
        } else {
            DynamicDTO dynamicDTO = initDynamicDTO(creator.getUserId(), memo, null,
                    memoHolder, null, null, null);
            fillRefInfoDynamicDTO(dynamicDTO, data);
            if (Objects.equals(businessType, XbbRefTypeEnum.CALL_CENTER.getCode())) {
                dynamicDTO.setLogType(ProjectLogEnum.CALL_LOG.getSubType());
            } else {
                // 客户旅程修复 logType
                // dynamicDTO.setLogType(BasicConstant.ZERO);
                dynamicDTO.setLogType(ProjectLogEnum.CUSTOMER_COMMUNICATE_CREATE.getSubType());
            }
            if (Objects.nonNull(dynamicRefInfoDTO)) {
                BeanUtil.copyProperties(dynamicRefInfoDTO, dynamicDTO, true);
            }
            dynamicDTOS.add(dynamicDTO);
        }

        insertDynamic(dynamicDTOS, saasFormSaveDTO.getCorpid());
    }

    private void customerCommunicateBatchDeleteUpRefDynamic(JSONObject data, FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<DynamicDTO> dynamicDTOS) {
        // 跟进信息
        String communicateInfo = data.getString(CommunicateBaseEnum.MEMO.getAttr());
        communicateInfo = StringUtil.isEmpty(communicateInfo) ? "--" : communicateInfo;
        // 跟进时间
        String communicateDateTime = DateTimeUtil.getStringEpochSecond(data.getLong(CommunicateBaseEnum.COMMUNICATE_TIME.getAttr()), DateTimeUtil.SDFYMDHM);
        List<String> memoHolder = DynamicDTO.initMemoHolder(formDataDeleteBatchDTO.getLoginUserName(), communicateDateTime, communicateInfo);
        // 可以关联多联系人
        JSONArray contactIdArr = data.getJSONArray(CommunicateBaseEnum.CONTACT.getAttr());
        if (Objects.nonNull(contactIdArr) && !contactIdArr.isEmpty()) {
            List<Long> contactIds = contactIdArr.toJavaList(Long.class);
            for (int i = 0; i < contactIds.size(); i++) {
                DynamicDTO dynamicDTO = initDynamicDTO(formDataDeleteBatchDTO.getUserId(), CrmLogMemoConstant.DYNAMIC_USER_COMMUNICATE_DELETE, null,
                        memoHolder, null, null, null);
                if (i == 0) {
                    fillRefInfoDynamicDTO(dynamicDTO, data);
                }
                dynamicDTO.setContactId(contactIds.get(i));
                // 客户旅程修复
                // 区别于其他业务日志
                // dynamicDTO.setLogType(BasicConstant.ZERO);
                dynamicDTO.setLogType(ProjectLogEnum.CUSTOMER_COMMUNICATE_DELETE.getSubType());
                dynamicDTOS.add(dynamicDTO);
            }
        } else {
            DynamicDTO dynamicDTO = initDynamicDTO(formDataDeleteBatchDTO.getUserId(), CrmLogMemoConstant.DYNAMIC_USER_COMMUNICATE_DELETE, null,
                    memoHolder, null, null, null);
            fillRefInfoDynamicDTO(dynamicDTO, data);
            // 客户旅程修复
            // dynamicDTO.setLogType(BasicConstant.ZERO);
            dynamicDTO.setLogType(ProjectLogEnum.CUSTOMER_COMMUNICATE_DELETE.getSubType());
            dynamicDTOS.add(dynamicDTO);
        }
    }

    private void fillRefInfoDynamicDTO(DynamicDTO dynamicDTO, JSONObject data) {
        refTextToLogTypeMap.forEach((refText, logType) -> {
            if (Objects.equals(refText, CommunicateBaseEnum.CONTACT.getAttr())) {
                return;
            }
            Long dataId = data.getLong(refText);
            Integer businessType = data.getInteger(CommunicateBaseEnum.COMMUNICATE_BUSINESS_TYPE.getAttr());
            if (Objects.nonNull(dataId)) {
                if (Objects.nonNull(logType)) {
                    initMainBusinessIdOrRefIdByLogType(logType, dynamicDTO, dataId);
                } else {
                    // 跟进涉及到合同和机会的id在跟进枚举中都是CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr()，所以指定不了 logType
                    XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                    switch (xbbRefTypeEnum) {
                        case CONTRACT:
                            dynamicDTO.setContractId(dataId);
                            break;
                        case SALES_OPPORTUNITY:
                            dynamicDTO.setOpportunityId(dataId);
                            break;
                        default:
                            break;
                    }
                }
            }
        });
    }
}
